package cn.likun.kit.datacast;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import cn.likun.kit.validate.ValidateCommons;
import cn.likun.kit.validate.ValidateDataType;

/**
 *<p>数据转化通用工具</p>
 */
public class CastCommons {
	
	/**
	 * <p>将字符串转换 byte[] , 如果无法进行转换则返回null</p>
	 * @param str
	 * @param encode
	 * @return
	 */
	public static byte[] stringToBytes(String str, String encode) {
		byte[] bytes = null;
		if (ValidateCommons.isNotEmpty(str)) {
			try {
				if (ValidateCommons.isEmpty(encode)) {
					bytes = str.getBytes();
				} else {
					bytes = str.getBytes(encode);
				}
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
		return bytes;
	}
	
	/**
	 * <p>将字符串转换 byte[] , 如果无法进行转换则返回null</p>
	 * @param str
	 * @return
	 */
	public static byte[] stringToBytes(String str) {
		return stringToBytes(str, null);
	}
	/**
	 * <p>字符串转换为短整型,如果无法进行转换则返回null</p>
	 * @param str
	 * @return
	 */
	public static Short stringToShort(String str) {
		Short st = null;
		if (ValidateDataType.validateShort(str)) {
			st = Short.parseShort(str);
		}
		return st;
	}
	/**
	 *  <p>描述：字符串转换为整型，如果无法进行转换则返回 null</p>
	 * @param str
	 * @return
	 */
	public static Integer stringToInteger(String str) {
		Integer ir = null;
		if (ValidateDataType.validateInteger(str)) {
			ir = Integer.parseInt(str);
		}
		return ir;
	}
	/**
	 * <p>方法名：stringToLong</p>
	 * <p>描述：字符串转换为长整型，如果无法进行转换则返回 null</p>
	 * @param str 需转换的字符串
	 * @return Long
	 */
	public static Long stringToLong(String str) {
		Long lg = null;
		if (ValidateDataType.validateLong(str)) {
			lg = Long.parseLong(str);
		}
		return lg;
	}
	
	/**
	 * <p>方法名：stringToFloat</p>
	 * <p>描述：字符串转换为单精度浮点型，如果无法进行转换则返回 null</p>
	 * @param str 需转换的字符串
	 * @return Float
	 */
	public static Float stringToFloat(String str) {
		Float ft = null;
		if (ValidateDataType.validateFloat(str)) {
			ft = Float.parseFloat(str);
		}
		return ft;
	}
	
	/**
	 * <p>方法名：stringToDouble</p>
	 * <p>描述：字符串转换为双精度浮点型，如果无法进行转换则返回 null</p>
	 * @param str 需转换的字符串
	 * @return Double
	 */
	public static Double stringToDouble(String str) {
		Double de = null;
		if (ValidateDataType.validateDouble(str)) {
			de = Double.parseDouble(str);
		}
		return de;
	}
	
	/**
	 * <p>方法名：stringToDate</p>
	 * <p>描述：字符串转换为时间，如果无法进行转换则返回 null</p>
	 * @param str 需转换的字符串
	 * @param format 时间格式
	 * @return Date
	 */
	public static Date stringToDate(String str, String format) {
		Date date = null;
		if (ValidateDataType.validataDate(str, format)) {
			SimpleDateFormat sfd = new SimpleDateFormat(format);
			try {
				date = sfd.parse(str);
			} catch (ParseException e) {
				date = null;
			}
		}
		return date;
	}
	/**
	 * <p>方法名：numberToString</p>
	 * <p>描述：数字类型转换为字符串，如果无法进行转换则返回 null</p>
     * @param number 需转换的数字
     * @param format 格式化数字，统一转换后的字符串长度，长度不够在前面补零。如果传入的数字为浮点型则会在整数、小数部分分别补format长度的零
	 * @return String
	 */
	public static String numberToString(Number number, Integer format) {
		String str = null;
		if (ValidateCommons.isNotEmpty(number)) {
			// 处理大数字科学计数法
			DecimalFormat df = new DecimalFormat("#.#");
			df.setMaximumIntegerDigits(16);
			df.setMaximumFractionDigits(16);
			str = df.format(number);
			if (ValidateCommons.isNotEmpty(format, true, "0")) {
				if (Float.class.equals(number.getClass()) || Double.class.equals(number.getClass())) {
					String[] tempArray = str.split("\\.");
					String prefix = tempArray[0];
					String suffix = tempArray[1];
					for (int i = prefix.length(); i < format; i++) {
						prefix = "0" + prefix;
					}
					for (int i = suffix.length(); i < format; i++) {
						suffix = suffix + "0";
					}
					str = new StringBuffer().append(prefix).append(".").append(suffix).toString();
				} else {
					for (int i = str.length(); i < format; i++) {
						str = "0" + str;
					}
				}
			}
		}
		return str;
	}

	/**
	 * <p>方法名：numberToString</p>
	 * <p>描述：数字类型转换为字符串，如果无法进行转换则返回 null</p>
     * @param number 需转换的数字
	 * @return String
	 */
	public static String numberToString(Number number) {
		return numberToString(number, 0);
	}

	/**
	 * <p>方法名：dateToString</p>
	 * <p>描述：时间转换为字符串，如果无法进行转换则返回 null</p>
	 * @param date 需转换的时间
	 * @param format 时间格式
	 * @return String
	 */
	public static String dateToString(Date date, String format) {
		String str = null;
		if (ValidateCommons.isNotEmpty(date)) {
			SimpleDateFormat sfd = new SimpleDateFormat(format);
			str = sfd.format(date);
		}
		return str;
	}

	/**
	 * <p>方法名：to</p>
	 * <p>描述：将数据转换为指定类型</p>
	 * @param obj 数据
	 * @param targetClass 目标类型
	 * @return 转换后的值
	 */
	public static Object to(Object obj, Class<?> targetClass) {
		String fromClassName = obj.getClass().getName();
		String targetClassName = targetClass.getName();
		// TODO 此处需要大量枚举
		if (BigDecimal.class.getName().equals(fromClassName)) {
			BigDecimal bd = (BigDecimal) obj;
			if (Double.class.getName().equals(targetClassName) || double.class.getName().equals(targetClassName)) {
				obj = bd.doubleValue();
			} else if (Float.class.getName().equals(targetClassName) || float.class.getName().equals(targetClassName)) {
				obj = bd.floatValue();
			} else if (Integer.class.getName().equals(targetClassName) || int.class.getName().equals(targetClassName)) {
				obj = bd.intValue();
			} else if (Long.class.getName().equals(targetClassName) || long.class.getName().equals(targetClassName)) {
				obj = bd.longValue();
			} else if (Short.class.getName().equals(targetClassName) || short.class.getName().equals(targetClassName)) {
				obj = bd.shortValue();
			}
		} else if (BigInteger.class.getName().equals(fromClassName)) {
			BigInteger bi = (BigInteger) obj;
			if (Double.class.getName().equals(targetClassName) || double.class.getName().equals(targetClassName)) {
				obj = bi.doubleValue();
			} else if (Float.class.getName().equals(targetClassName) || float.class.getName().equals(targetClassName)) {
				obj = bi.floatValue();
			} else if (Integer.class.getName().equals(targetClassName) || int.class.getName().equals(targetClassName)) {
				obj = bi.intValue();
			} else if (Long.class.getName().equals(targetClassName) || long.class.getName().equals(targetClassName)) {
				obj = bi.longValue();
			} else if (Short.class.getName().equals(targetClassName) || short.class.getName().equals(targetClassName)) {
				obj = bi.shortValue();
			}
		}
		return obj;
	}
}
